<template>
  <div class="dashboard-container">
    <github-corner class="github-corner" />
    <!-- 数据卡片 -->
    <el-row :gutter="10" class="mt-5">
      <el-col :xs="24" :sm="4" :lg="4">
        <el-card shadow="never">
          <el-upload
            drag
            class="avatar-uploader"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            :http-request="customHttpRequest"
            action="#"
            :accept="'image/*'"
          >
            <img
              v-if="imageUrl"
              :src="imageUrl"
              style="width: 200px; height: 240px"
            />
            <el-icon
              v-if="imageUrl"
              style="margin-right: 10px"
              @click="handlePictureCardPreview"
            >
              <zoom-in />
            </el-icon>
            <el-icon v-if="imageUrl" @click="handleRemove"><Delete /></el-icon>
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>

            <div class="el-upload__text">
              Drop file here or
              <em>click to upload</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                jpg/png files with a size less than 2MB
              </div>
            </template>
          </el-upload>
          <div class="generate">
            <el-button
              :loading="loading"
              class="bottom-span"
              type="primary"
              round
              @click="handleGenerate"
            >
              生成图片
            </el-button>
          </div>
        </el-card>
      </el-col>
      <el-col :xs="24" :sm="6" :lg="18" class="container">
        <template
          v-for="resultImageUrl in resultImageUrlList"
          :key="resultImageUrl.id"
        >
          <el-image v-if="resultImageUrl.generated" class="result-image">
            <template #error>
              <div class="image-slot">正在生成中，请稍后...</div>
            </template>
          </el-image>

          <el-image
            v-else
            :src="resultImageUrl.imageUrl"
            class="result-image"
          />
        </template>
      </el-col>
    </el-row>

    <el-row :gutter="10" class="mt-5">
      <el-col v-loading="loading" :xs="24" :span="24">
        <!-- 样式图片 -->
        <el-card>
          <template #header>
            <div class="flex-x-between">
              <div class="flex-y-center">
                样式图片
                <el-tooltip
                  effect="dark"
                  content="点击试试下载"
                  placement="bottom"
                >
                  <el-icon
                    class="cursor-pointer hover:color-#4080FF ml-1"
                    name="el-icon-download"
                    @click="handleDownload"
                  >
                    <Download />
                  </el-icon>
                </el-tooltip>
              </div>

              <el-radio-group
                v-model="dataRange"
                size="small"
                @change="loadStyleImageList"
              >
                <el-radio-button label="top 10" :value="10" />
                <el-radio-button label="top 30" :value="30" />
              </el-radio-group>
            </div>
          </template>
          <div
            v-for="image in styleImageList"
            :key="image.imageUrl"
            class="image-container"
          >
            <el-image
              class="image"
              style="width: 160px; height: 160px; padding: 5px"
              :src="image.imageUrl"
              :zoom-rate="1.2"
              :max-scale="7"
              :min-scale="0.2"
              :initial-index="4"
              fit="cover"
            />
            <el-checkbox
              v-model="image.checked"
              class="checkbox"
              @click="handleCheckChange(image.id)"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "Dashboard",
  inheritAttrs: false,
});

import { ref } from "vue";
import { ElMessage } from "element-plus";
import { Plus } from "@element-plus/icons-vue";

import type {
  UploadProps,
  UploadRequestOptions,
  UploadFile,
} from "element-plus";

import ImageAPI, { type ImageVO } from "@/api/system/image";
import StyleImageAPI, { StyleImageVO } from "@/api/system/styleImage";
import ResultImageAPI, {
  GenerateResultImageForm,
  GenerateResultImageSuccessMessage,
} from "@/api/system/resultImage";
import WebSocketManager from "@/utils/websocket";
import { WebSocketEnum } from "@/enums/WebSocketEnum";

const imageUrl = ref("");
const dataRange = ref(10);

const styleImageList = ref<StyleImageVO[]>([]);

const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile
) => {
  imageUrl.value = URL.createObjectURL(uploadFile.raw!);
};

const loading = ref(false);
const customHttpRequest = async (options: UploadRequestOptions) => {
  const { file, onSuccess, onError } = options;
  ImageAPI.create(file)
    .then((data) => {
      generateImageForm.value.id = data;
    })
    .finally(() => {
      loading.value = false;
    });
  loadStyleImageList();
};

const loadStyleImageList = () => {
  const queryParams: PageQuery = {
    pageNo: 1,
    pageSize: dataRange.value,
  };
  StyleImageAPI.getList(queryParams)
    .then((data) => {
      styleImageList.value = data;
    })
    .finally(() => {
      loading.value = false;
    });
};

const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  if (!(rawFile.type === "image/jpeg" || rawFile.type === "image/png")) {
    ElMessage.error("Avatar picture must be JPG/PNG format!");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("Avatar picture size can not exceed 2MB!");
    return false;
  }
  return true;
};

const handleDownload = (e: any) => {
  console.info(e);
};

// 图片放大与删除
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const handleRemove = (event: any) => {
  event.stopPropagation();
  imageUrl.value = "";
  generateImageForm.value.id = 0;
  resultImageUrlList.value = [];
};

const handlePictureCardPreview = (event: any) => {
  event.stopPropagation();
  dialogImageUrl.value = imageUrl.value;
  dialogVisible.value = true;
};

// 生成图片
const generateImageForm = ref<GenerateResultImageForm>({
  id: 0,
  styleImageId: 0,
});

const handleCheckChange = (id: number) => {
  styleImageList.value.map(function (style) {
    //非当前选中元素都修改为false，保持单选
    if (style.id !== id) {
      style.checked = false;
    }
    generateImageForm.value.styleImageId = id;
    return style;
  });
};

// const generateLoading = ref(false);
const resultImageUrlList = ref<GenerateResultImageSuccessMessage[]>([]);

const handleGenerate = () => {
  if (generateImageForm.value.id === 0) {
    ElMessage.error("请上传图片");
    return;
  }
  if (generateImageForm.value.styleImageId === 0) {
    ElMessage.error("请选择图片样式");
    return;
  }
  ResultImageAPI.generate(generateImageForm.value)
    .then((data) => {
      data.map((t) => {
        t.generated = true;
        resultImageUrlList.value.unshift(t);
      });
    })
    .finally(() => {});
};

onMounted(() => {
  WebSocketManager.subscribeToUser(
    WebSocketEnum.GENERATE_RESULT_IMAGE_SUCCESS,
    (data) => {
      const messageData = JSON.parse(data) as GenerateResultImageSuccessMessage;
      console.log("收到消息：", messageData, generateImageForm.value.id);
      if (messageData.originalImageId == generateImageForm.value.id) {
        // 不重复添加图片，用id判断重复
        messageData.generated = false;
        const index = resultImageUrlList.value.findIndex(
          (el) => el.id === messageData.id
        );
        if (index != -1) {
          resultImageUrlList.value.splice(index, 1, messageData);
        } else {
          resultImageUrlList.value.unshift(messageData);
        }

        console.log("数据正确：", messageData, generateImageForm.value.id);
      }
    }
  );
});
</script>

<style lang="scss" scoped>
.dashboard-container {
  position: relative;
  padding: 12px;

  .github-corner {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
    border: 0;
  }
}
.avatar-uploader .avatar {
  width: 100px;
  height: 100px;
  display: block;
  max-width: 100px;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  text-align: center;
}

.container {
  position: relative; /* 设定父元素为相对定位 */
  /* border: 1px solid #000;  */
  /* 边框用于可视化 */
}

/*
position: absolute;
  bottom: 0;  设定元素底部与父元素底部对齐 
  left: 0%; 水平居中，如果需要的话
*/
.generate {
  text-align: center;
}

.bottom-span {
  margin-top: 5px;
}

.image-container {
  position: relative;
  display: inline-block;
}

.image {
  width: 300px; /* Adjust as needed */
  height: auto;
}

.checkbox {
  position: absolute;
  top: 15px; /* Adjust as needed */
  right: 15px; /* Adjust as needed */
  transform: translate(50%, -50%);
}

.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: var(--el-fill-color-light);
  color: var(--el-text-color-secondary);
  font-size: 16px;
}
.result-image {
  width: 180px;
  height: 232px;
  margin-left: 10px;
  margin-bottom: 7px;
}
</style>
